package com.qipay.admin.login;


import com.qipay.admin.BaseController;
import com.qipay.baas.model.Cp;
import com.qipay.baas.model.Peizhi;
import com.qipay.baas.model.User;
import com.qipay.cp.CpService;
import com.qipay.ips.service.IpsService;
import com.qipay.notice.NoticeService;
import com.qipay.security.UserDetailsServiceImpl;
import com.qipay.user.service.UserService;
import com.qipay.utils.Result;
import com.qipay.utils.VerifyCodeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

@Controller
@RequestMapping("/login")
public class LoginController extends BaseController {

    private final static String VALID_CODE_SESSION_NAME = "validCodeSession";
    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    NoticeService noticeService;

    @Autowired
    UserService userService;

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    CpService cpService;

    @Autowired
    IpsService ipsService;

    @Value("${ip.sign}")
    protected Boolean ipSign;

    private static Logger logger = LoggerFactory.getLogger(LoginController.class);

    @RequestMapping(value = "/sign", method = RequestMethod.GET)
    public ModelAndView sign() {
        return createModelAndView("sign");
    }

    @RequestMapping(value = "/sign/save", method = RequestMethod.POST)
    public String signSave(@RequestParam Long uid) {
        if (uid != null && uid.longValue() > 0) {
            cpService.updateContractState(uid, (byte) 1);
        }
        return "redirect:/login";
    }

    @RequestMapping(value = "/pass", method = RequestMethod.POST)
    @ResponseBody
    public Result<String> loginWithPass(
            HttpServletRequest request,
            @RequestParam String password,
            @RequestParam String username,
            @RequestParam String validCode) {

        Peizhi peizhi = noticeService.getPeizhi();
        try {
            String content = new String(peizhi.getContent().getBytes("iso-8859-1"), "UTF-8");
            System.out.println("==" + content);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }


        request.getSession().setAttribute("peizhi", peizhi);

        Result<String> resultSample = new Result<String>();


        if (StringUtils.isAnyEmpty(password, username)) {
            resultSample.setCode(400);
            resultSample.setMsg("参数错误");
            return resultSample;
        }

        if (StringUtils.isEmpty(username) || username.length() >= 15) {
            resultSample.setCode(400);
            resultSample.setMsg("请输入正确的姓名");
            return resultSample;
        }

        //User user = userService.Login(username, password);
        String passWordMd5 = passwordEncoder.encode(password);
        User user = userService.getByName(username);
        if (user == null) {
            resultSample.setCode(400);
            resultSample.setMsg("用户名或密码错误");
            return resultSample;
        }
//        passWordMd5 = user.getPwd();
        if (!user.getPwd().equals(passWordMd5)) {
            resultSample.setCode(400);
            resultSample.setMsg("用户名或密码错误");
            return resultSample;
        }

        if(ipSign){
            //判定ip
            if (!ipsService.checkIp(username, request) || user.getLevel() == null) {
                resultSample.setCode(400);
                resultSample.setMsg("ip地址无效");
                return resultSample;
            }
        }

        if (user.getLevel() < 500 ) {
            Cp cpUser = cpService.getOneById(Long.parseLong(user.getName()));
            if (cpUser == null) {
                resultSample.setCode(400);
                resultSample.setMsg("用户不存在");
                return resultSample;
            }
            if (cpUser.getAccountState() == null) {
                resultSample.setCode(400);
                resultSample.setMsg("帐号已被禁用");
                return resultSample;
            }
            if (cpUser.getAccountState() != 2) {
                resultSample.setCode(400);
                resultSample.setMsg("帐号已被禁用");
                return resultSample;
            }
            if (cpUser.getContractState() == null) {
                resultSample.setCode(440);
                resultSample.setMsg("帐号未签约");
                return resultSample;
            }
            if (cpUser.getContractState() != 1) {
                resultSample.setCode(440);
                resultSample.setMsg("帐号未签约");
                resultSample.setData(user.getName());
                return resultSample;
            }
        }
        //todo  这里的代码先注掉,不懂为什么这么写,乱放大权限
        /*else {
            user.setLevel(1000);
        }*/

        try {
            UsernamePasswordAuthenticationToken authRequest =
                    new UsernamePasswordAuthenticationToken(user.getName(), user.getPwd());

            Authentication authentication = authenticationManager.authenticate(authRequest);
            SecurityContext securityContext = SecurityContextHolder.getContext();
            securityContext.setAuthentication(authentication);

            // Create a new session and add the security context.
            HttpSession session = request.getSession(true);
            session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
            session.setAttribute("user", user);

        } catch (Exception e) {
            SecurityContextHolder.getContext().setAuthentication(null);
            logger.error("Failure in autoLogin", e);
        }

        try {
            HttpSession session = request.getSession(true);
            DefaultSavedRequest defaultSavedRequest = (DefaultSavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST");
            if (defaultSavedRequest != null) {
                resultSample.setData(defaultSavedRequest.getRedirectUrl());
            }
        } catch (Exception e) {
            logger.error("Failure in RedirectUrl", e);
        }

        resultSample.setCode(200);
        return resultSample;
    }

    @RequestMapping(value = "", method = RequestMethod.GET)
    public ModelAndView login(HttpServletResponse response,
                              HttpServletRequest request) throws IOException {

        HttpSession session = request.getSession(true);
        Object securityContext = session.getAttribute("SPRING_SECURITY_CONTEXT");
        if (securityContext != null) {
            response.sendRedirect(request.getContextPath());
            return null;
        }

        ModelAndView view = createModelAndView("login");
//        String state = weixinService.createState(request);
//        logger.info("生成微信登录的state:" + state);
//        view.addObject("state", state);
        return view;
    }

    @RequestMapping(value = "/islogin", method = RequestMethod.GET)
    public Result isLogin(
            @AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser) throws IOException {
        Result resultSample = new Result();

        if (loginUser != null) {
            resultSample.setCode(200);
            resultSample.setMsg("您已登录");
            return resultSample;
        }

        resultSample.setCode(400);
        resultSample.setMsg("请先登录");
        return resultSample;
    }

    @RequestMapping(value = "/validcode")
    public void ValidCodeTest(HttpServletRequest request, HttpServletResponse response,
                              @RequestParam @NotNull int w, @RequestParam @NotNull int h) throws IOException {
        response.addHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");

        //生成随机字串
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        //存入会话session
        HttpSession session = request.getSession(true);
        session.setAttribute(VALID_CODE_SESSION_NAME, verifyCode.toLowerCase());

        VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);
    }

    @RequestMapping(value = "/test/user", method = RequestMethod.GET)
    public @ResponseBody
    User getUserByTest(
            HttpServletRequest request, HttpServletResponse response
    ) {
        return userService.getByName("dong");
    }

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ModelAndView test() {
        System.out.println("登陆测试");
        ModelAndView view = createModelAndView("login");
        return view;
    }
}